package com.sann.config;

import com.sann.entity.Person;
import com.sann.filter.MyTypeFilter;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

/** 该注解表明该配置类==配置文件bean.xml */
@Configuration("conf")
/** MYNOTICE ①@Repeatable(ComponentScans.class)表明它所标注的注解是可重复的 ②它的value属性指示可重复注解类型的包含注解类型
 * @Repeatable(ComponentScans.class)  -->jdk1.8才提供,之前的版本说明配置类只能添加一次@ComponentScan，此时要想添加多个@ComponentScan
 * 就得改用spring4.3版本，用@ComponentScans(内部配置多个@ComponentScan)
 * public @interface ComponentScan {}
 * 由@Repeatable自身定义可知，它出现在jdk1.8，如果jdk低于1.8，public @interface ComponentScan上就无该注解。该注解用于定义其它注解是可以重复的；
 * ComponentScans.class 指示可重复注解类型的包含注解类型，就是说 ComponentScans 注解类型可以包含 ComponentScan 注解
 * includeFilters: 按照注解过滤包含 @Controller 的扫描进容器
 * excludeFilters：按照注解过滤排除 @Service、@Repository 的不要扫描进容器
 */
@ComponentScans({
        @ComponentScan(value = "com.sann",
            includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes ={Controller.class}),
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)
                }, useDefaultFilters = false),

        @ComponentScan(
                value = "com.sann",
                excludeFilters = {
                    @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class,
                            Repository.class})})
})
public class MainConfig {

    /** Bean名 == 方法名 person01 */
    @Bean
//    @Scope("prototype")
    /**对于单实例Bean，容器启动就加载Bean进容器，通过@Lazy注解可以懒加载，按需要再加载*/
    @Lazy
    public Person person01(){
        return new Person("张三", 18);
    }

    /** Bean被命名为person02 */
    @Bean("person02")
    public Person person(){
        return new Person("李四", 19);
    }
}
